package org.xurui.sxl.protocol.command.impl;

import lombok.extern.slf4j.Slf4j;
import org.jetlinks.core.message.CommonDeviceMessage;
import org.jetlinks.core.message.DeviceMessage;
import org.jetlinks.core.message.codec.EncodedMessage;
import org.jetlinks.core.message.codec.FromDeviceMessageContext;
import org.jetlinks.core.message.function.FunctionInvokeMessage;
import org.jetlinks.core.message.function.FunctionInvokeMessageReply;
import org.jetlinks.core.message.function.FunctionParameter;
import org.springframework.util.StringUtils;
import org.xurui.sxl.protocol.cache.ConcurrentMapCache;
import org.xurui.sxl.protocol.command.CmdCodec;
import org.xurui.sxl.protocol.enums.CommandEnum;
import org.xurui.sxl.protocol.utils.BinaryUtils;
import org.xurui.sxl.protocol.utils.NumberUtils;
import org.xurui.sxl.protocol.utils.SxlMessageUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 设置多个白名单号码指令
 */
@Slf4j
public class CmdCodec_WLALL implements CmdCodec {
    @Override
    public boolean supportsCmd(String cmd) {
        return CommandEnum.WLALL.name().equals(cmd);
    }

    @Override
    public boolean supportsRelayCmd() {
        return true;
    }

    @Override
    public List<DeviceMessage> parsePayload(String payload, FromDeviceMessageContext context) {
        //设备回复格式：*XX,YYYYYYYYYYYYYYY,V4,WLALL,seq,para,HHMMSS,S,latitude,D,longitude,G,speed,pdop,DDMMYY,tracker_status#
        //设备回复示例：*TJ,2020916012,V4,WLALL,130305,1,13612345678,1,2,13612345678,1,3,13612345678,1,4,13612345678,1,5,1
        //3612345678,2,6,13612345678,2,7,13612345678,2,8,13612345678,2,9,13612345678,2,10,13612345678,2,1303
        //06,A,2212.8745,N,11346.6574,E,14.28,2.8,220902,FFFFFFFF#
        FunctionInvokeMessageReply report = FunctionInvokeMessageReply.create();
        String[] payloadArr = payload.replaceAll("\\*","").split(",");
        String deviceId = payloadArr[1];
        report.setDeviceId(deviceId);
        Object messageIdObj = ConcurrentMapCache.getInstance().getAndRemove(deviceId+"_"+CommandEnum.WLALL.name()+"_"+payloadArr[4]);
        String messageId = messageIdObj==null?null:messageIdObj.toString();
        if(messageId==null){
            messageId = deviceId+"_"+payloadArr[4];
        }

        report.setFunctionId(CommandEnum.WLALL.name());
        report.setMessageId(messageId);
        report.setTimestamp(System.currentTimeMillis());
        String[] paraArr=Arrays.copyOfRange(payloadArr,4,payloadArr.length-10);
        String para="";
        for (int i=1;i<paraArr.length;i++){
            // System.out.println(paraArr[i]);
            if(i==1){
                para=paraArr[i];
            }else{
                para=para+","+paraArr[i];
            }
        }
        int j=4+paraArr.length-1;

        Map<String, Object> properties = new HashMap<>();
        properties.put("para",para);
        properties.put("uptime",payloadArr[j+1]);
        properties.put("s",payloadArr[j+2]);
        properties.put("latitude",BinaryUtils.getWgs84LonLat(payloadArr[j+3],"lat"));
        properties.put("d",payloadArr[j+4]);
        properties.put("longitude",BinaryUtils.getWgs84LonLat(payloadArr[j+5],"lon"));
        properties.put("g",payloadArr[j+6]);
        properties.put("speed", NumberUtils.parseDouble(payloadArr[j+7]));
        properties.put("pdop",NumberUtils.parseDouble(payloadArr[j+8]));
        properties.put("upday", payloadArr[j+9]);
        String trackerStatusHex = payloadArr[j+10];


        Map<String,Object> trackerStatusMap = parseTrackerStatus(trackerStatusHex);
        properties.put("trackerstatus",trackerStatusMap);
        report.setOutput(properties);

        //TODO 更新状态
        return genDeviceMessage(report);
    }

    @Override
    public EncodedMessage encodeMessage(CommonDeviceMessage message,String zzs) {
        //平台下发消息
        //格式：*XX,YYYYYYYYYYYYYYY,WLALL,HHMMSS,wl-num,wl-phone,wl_type,…#
        //例子 1：*TJ,2020916012,WLALL,130305,1,13612345678,1,2,13612345678,1,3,13612345678,1,4,13612345678,1,5,13612345678,2,6,13612345678,2,7,13612345678,2,8,13612345678,2,9,13612345678,2,10,13612345678,2#
        //例 2：删 除 *TJ,2020916012,WLALL,130305,1,,,2,,,3,,,4,,,5,,,6,,,7,,,8,,,9,,,10,,#
        //参数说明：wl-num 白名单编号,取值 1-20，展示的位置，可以设置 20 个白名单号码
        //参数说明：wl-phone 白名单电话号码，如果为空，则表示删除该位置号码
        //参数说明：wl_type 白名单类型，1 表示亲情号，2 表示其他号；允许不填，如果不填写，则必须用,隔开
        //        不再使用，如设备有 5 个按键，那么前 5 个白名单对应 5 个可拨打的亲情号。即 wl_type 可不填。
        if(message instanceof FunctionInvokeMessage) {
            FunctionInvokeMessage m = (FunctionInvokeMessage) message;
            List<FunctionParameter> params = m.getInputs();
            Map<String, Object> paramsMap = params.stream()
                .collect(Collectors.toMap(FunctionParameter::getName, FunctionParameter::getValue));
            String  wlNumWlPhoneWlType="";
            if(paramsMap.get("wlNumWlPhoneWlType")!=null && !paramsMap.get("wlNumWlPhoneWlType").equals("")) {
                wlNumWlPhoneWlType=paramsMap.get("wlNumWlPhoneWlType").toString();
            }
         /*   String wlNum="";
            if(paramsMap.get("wlNum")!=null && !paramsMap.get("wlNum").equals("")) {
                wlNum=paramsMap.get("wlNum").toString();
            }

            if("0".equals(wlNum)){
                log.error("白名单电话号码为空请重新填写");
                return null;
            }*/

           /* String[] wlPhones = new String[]{};
            String[] wlTypes = new String[]{};

            if(paramsMap.get("wlPhone")!=null && !paramsMap.get("wlPhone").equals("")) {
                wlPhones=paramsMap.get("wlPhone").toString().split(",");
            }

            if(paramsMap.get("wlType")!=null && !paramsMap.get("wlType").equals("")) {
                wlTypes=paramsMap.get("wlType").toString().split(",");
            }

            if(wlPhones.length==0){
                log.error("白名单电话号码为空请重新填写");
                return null;
            }

            if(wlPhones.length>0){
                if(wlPhones.length!=wlTypes.length){
                    log.error("该参数白名单电话号码长度与白名单类型长度不一样请重新填写白名单类型");
                    return null;
                }
            }*/
            if(StringUtils.isEmpty(wlNumWlPhoneWlType)){
                log.error("白名单电话号码为空请重新填写");
                return null;
            }

            //String[] mesArr= paramsMap.toString().split(",");

            String time = SxlMessageUtils.getTimeHHMMSS();//DateFormatUtils.format(new Date(),"HHmmss");
            /*StringBuffer sb = new StringBuffer();
            sb.append("*");
            sb.append(zzs);//TODO 需要修改成根据设备动态加载
            sb.append(",");
            sb.append(message.getDeviceId());
            sb.append(",");
            sb.append(CommandEnum.WLALL.name());
            sb.append(",");
            sb.append(time);
            for (int i=0;i<wlPhones.length;i++){
                sb.append(",");
                sb.append((i+1));
                sb.append(",");
                sb.append(wlPhones[i]);
                sb.append(",");
                sb.append(wlTypes[i]);
            }
            *//*if(mesArr.length>0){
                for (int i=0;i<mesArr.length;i++){
                    sb.append(",");
                    sb.append(mesArr[i]);
                }
            }*//*
            sb.append("#");*/

            SxlMessageUtils.SxlCmd sxlCmd=SxlMessageUtils.SxlCmd.getInstance();
            sxlCmd.appendAndAddSeparator(zzs)
                .appendAndAddSeparator(message.getDeviceId())
                .appendAndAddSeparator(CommandEnum.WLALL.name())
                .appendAndAddSeparator(time)
                .append(wlNumWlPhoneWlType);

            /*for (int i=0;i<wlPhones.length;i++){
                String wlPhone="";
                if(!"_".equals(wlPhones[i])){
                    wlPhone=wlPhones[i];
                }
                String wlType="";
                if(!"_".equals(wlTypes[i])){
                    wlType=wlTypes[i];
                }
                sxlCmd.append(SxlMessageUtils.CMD_SEPARATION)
                .appendAndAddSeparator(String.valueOf(i+1))
                .appendAndAddSeparator(wlPhone)
                .append(wlType);
            }*/
            ConcurrentMapCache.getInstance().set(message.getDeviceId()+"_"+CommandEnum.WLALL.name()+"_"+time,message.getMessageId(),60*3*1000);
            //return EncodedMessage.simple(Unpooled.wrappedBuffer(sb.toString().getBytes()));

            return sxlCmd.buildEncodeMessage();
        }else{
            if (log.isDebugEnabled()) {
                log.debug("非FunctionInvokeMessage指令{}消息{}",CommandEnum.WIFISCAN.name(),message);
            }
            return null;
        }

    }
}
